
#include <process.h>
#include "ThreadWin.h"
//#include "stdafx.h"  

ThreadRunReturn __stdcall threadFunction(void * object)
{
   Thread * thread = (Thread *) object;
   thread->run(thread->param);
   return  0;
}

Thread::Thread(ThreadRun _run)
{
   started = false;
   detached = false;
   run = _run;
}

Thread::~Thread()
{
   stop();
}

int Thread::start(void* pra)
{
   if (!started)
   {
	   param = pra;
	   if (threadHandle = (ThreadHandle)_beginthreadex(NULL, 0, threadFunction, this, 0, &threadID))
	   {
		   if (detached)
		   {
				CloseHandle(threadHandle);
		   }
		   started = true;
	   }
   }
   return started;
}

//wait for current thread to end.
DWORD Thread::join()
{
   DWORD status = (DWORD) NULL;
   if (started && !detached)
   {
	   WaitForSingleObject(threadHandle, INFINITE);
	   GetExitCodeThread(threadHandle, &status); 
	   CloseHandle(threadHandle);
	   detached = true;
   }

   return status;
}

void Thread::detach()
{
   if (started && !detached)
   {
		CloseHandle(threadHandle);
   }
   detached = true;
}

void Thread::stop()
{
   if (started && !detached)
   {
	   TerminateThread(threadHandle, 0);

	   //Closing a thread handle does not terminate 
	   //the associated thread. 
	   //To remove a thread object, you must terminate the thread, 
	   //then close all handles to the thread.
	   //The thread object remains in the system until 
	   //the thread has terminated and all handles to it have been 
	   //closed through a call to CloseHandle
	   CloseHandle(threadHandle);
	   detached = true;
   }
}

void Thread::sleep(unsigned int delay)
{
   ::Sleep(delay);
}

int Thread::createLock(ThreadLockType *lock) {
	InitializeCriticalSection(lock);
	return 0;
}
int Thread::lock(ThreadLockType *lock) {
	EnterCriticalSection(lock);
	return 0;
}
int Thread::tryLock(ThreadLockType *lock) {
	int rv = TryEnterCriticalSection(lock);
	if (rv != 0) {
		return GetLastError();
	} else {
		return 0;
	}
}
int Thread::unlock(ThreadLockType *lock) {
	LeaveCriticalSection(lock);
	return 0;
}
int Thread::destoryLock(ThreadLockType *lock) {
	DeleteCriticalSection(lock);
	return 0;
}
